#pragma once
#include<iostream>
#include<string>
#include<unistd.h>
#include<cstring>
#include<cassert>
#include<sys/types.h>
#include<sys/stat.h>
#include<sys/wait.h>
#include<vector>
#include<fcntl.h>
#include<sys/shm.h>
#include<sys/ipc.h>
using namespace::std;
char* SHM_FIFE = "./";
#define SIZE 4096

class shm
{
public:
    int getshm(int size)
    {
        int sign =0;
        if(_flag == 1)
        {
            sign = shmget(_key,SIZE,IPC_CREAT|IPC_EXCL|0666);
        }
        else
        {
            sign = shmget(_key,SIZE,IPC_CREAT|0666);
        }
        if(sign == -1)
        {
            cout <<"getshm:" << errno << strerror(errno) <<endl;
            exit(-1);
        }
        return sign;
    }
    key_t getkey(char* file,int pro_id)
    {
        key_t _key = ftok(file,pro_id);
        if(_key == -1)
        {
            cout <<"getkey:"<< errno << strerror(errno) <<endl;
            exit(-1);
        }
        return _key;
    }
    char* attchshm()
    {
        char* tmp = (char*)shmat(_id,nullptr,0);
        return tmp;
    }
    void delshm()
    {
        int sign = shmctl(_id,IPC_RMID,nullptr);
        assert(!(sign == -1));
    }
    void dattchshm()
    {
        if(_flag ==1) cout << "sever:断开通信" << endl;
        else cout << "client:断开通信" << endl;
        int sign = shmdt(_addr);
        assert(!(sign == -1));
    }
    void shmact()
    {
        cout << _flag << endl;
        if(_flag == 1)
        {
            cout << "sever:开始通信！" <<endl;
            int n=0;
            while(n<=26)
            {
                cout << _addr <<endl;
                fflush(stdout);
                n++;
                sleep(1);
            }
        }
        else
        {
            cout << "client:开始通信！" <<endl;
            char n='A';
            while(n<='Z')
            {
                _addr[n-'A'] = n;
                n++;
                _addr[n-'A'] = '\0';
                sleep(1);
            }
        }
    }
    shm(int flag,char* file,int pro_id)
    :_flag(flag)
    {
        umask(0);
        cout << flag <<endl;
        _key= getkey(file,pro_id);
        cout << "_key ="<<_key <<endl;
        _id = getshm(SIZE);
        cout << "id="<<_id <<endl;
        sleep(3);
        _addr = attchshm();
        cout << "链接成功!" <<endl;
        shmact();
    }
    ~shm()
    {
        dattchshm();
        if(_flag == 1) delshm();
    }
    
private:
    char* _addr;
    key_t _key;
    int _id;
    int _flag;
};
